package com.heima.user.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.heima.common.constants.message.FollowBehaviorConstants;
import com.heima.common.exception.CustException;
import com.heima.feigns.article.ArticleFeign;
import com.heima.model.article.pojos.ApAuthor;
import com.heima.model.behavior.dtos.FollowBehaviorDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.threadlocal.AppThreadLocalUtils;
import com.heima.model.user.dtos.UserRelationDto;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.user.pojos.ApUserFan;
import com.heima.model.user.pojos.ApUserFollow;
import com.heima.user.mapper.ApUser2Mapper;
import com.heima.user.mapper.ApUserFanMapper;
import com.heima.user.mapper.ApUserFollowMapper;
import com.heima.user.service.ApUserRelationService;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;

/**
 * @author Jt
 * @date 2021/4/21 20:25
 */
@Service
@Transactional
public class ApUserRelationServiceImpl implements ApUserRelationService {

    @Resource
    private ArticleFeign articleFeign;

    @Resource
    private ApUser2Mapper apUser2Mapper;

    @Resource
    private ApUserFollowMapper apUserFollowMapper;

    @Resource
    private ApUserFanMapper apUserFanMapper;

    @Resource
    private KafkaTemplate kafkaTemplate;

    @Override
    public ResponseResult follow(UserRelationDto dto) {
//        1. 校验参数
        if (ObjectUtils.isEmpty(dto.getOperation()) || dto.getOperation() < 0 || dto.getOperation() > 1) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID);
        }
//        2. 判断是否有作者
        if (ObjectUtils.isEmpty(dto.getAuthorId())) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID,"作者信息不存在");
        }
        ApAuthor apAuthor = articleFeign.selectById(dto.getAuthorId());
        if (ObjectUtils.isEmpty(apAuthor)) {
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID,"关注的用户不存在");
        }
//        3. 判断是否登录
        ApUser apUser = AppThreadLocalUtils.getUser();
        if (ObjectUtils.isEmpty(apUser)) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN);
        }
        if (dto.getOperation() == 0) {
//        4. 创建app用户关注和app用户粉丝
            return followByUserId(apUser.getId(),apAuthor.getUserId(),dto.getArticleId());
        } else {
//            取关
            return followCancelByUserId(apUser.getId(),apAuthor.getUserId());
        }
    }


    /**
     * 关注
     * @param userId 普通用户(当前的登录人)
     * @param followUserId 被关注的作者对应的apUser id
     * @param articleId 文章的id
     * @return
     */
    private ResponseResult followByUserId(Integer userId, Integer followUserId, Long articleId) {
//        获取被关注的作者对应的userId
        ApUser apUser = apUser2Mapper.selectById(followUserId);
        if (ObjectUtils.isEmpty(apUser)) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN,"关注的用户不存在");
        }
        if (userId.intValue() == apUser.getId().intValue()) {
            CustException.cust(AppHttpCodeEnum.NEED_LOGIN,"请不要关注你自己");
        }
        ApUserFollow apUserFollow = apUserFollowMapper.selectOne(Wrappers.<ApUserFollow>lambdaQuery()
                .eq(ApUserFollow::getFollowId, apUser.getId())
                .eq(ApUserFollow::getUserId, userId));
        if (apUserFollow != null) {
            CustException.cust(AppHttpCodeEnum.DATA_EXIST);
        }
        apUserFollow = new ApUserFollow();
        apUserFollow.setFollowId(followUserId);
        apUserFollow.setUserId(userId);
        apUserFollow.setLevel((short)1);
        apUserFollow.setIsNotice(true);
        apUserFollow.setFollowName(apUser.getName());
        apUserFollow.setCreatedTime(new Date());
        apUserFollowMapper.insert(apUserFollow);
//        保存被关注的作者对应的粉丝
        ApUserFan apUserFan = apUserFanMapper.selectOne(Wrappers.<ApUserFan>lambdaQuery()
                .eq(ApUserFan::getFansId, userId)
                .eq(ApUserFan::getUserId, followUserId));
        if (apUserFan != null) {
            CustException.cust(AppHttpCodeEnum.DATA_EXIST);
        }
        apUserFan = new ApUserFan();
        apUserFan.setUserId(followUserId);
        apUserFan.setCreatedTime(new Date());
        apUserFan.setLevel((short)0);
        apUserFan.setIsShieldComment(false);
        apUserFan.setIsShieldLetter(false);
        apUserFan.setIsDisplay(true);
        apUserFan.setFansId(userId.longValue());
//        粉丝的名称
        ApUser user = apUser2Mapper.selectById(userId);
        apUserFan.setFansName(user.getName());
        apUserFanMapper.insert(apUserFan);
//        记录下关注的行为
        FollowBehaviorDto followBehaviorDto = new FollowBehaviorDto();
        followBehaviorDto.setFollowId(userId);
        followBehaviorDto.setArticleId(articleId);
        followBehaviorDto.setUserId(apUser.getId());
//        异步发送消息 保存关注行为
        kafkaTemplate.send(FollowBehaviorConstants.FOLLOW_BEHAVIOR_TOPIC, JSON.toJSONString(followBehaviorDto));
//        返回结果
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


    /**
     * 取消关注
     * @param userId 普通用户
     * @Param followUserId 当前的登录人
     * @return
     */
    private ResponseResult followCancelByUserId(Integer userId, Integer followUserId) {
//        删除当前用户的关注的信息
        apUserFollowMapper.delete(Wrappers.<ApUserFollow>lambdaQuery()
        .eq(ApUserFollow::getFollowId,followUserId)
        .eq(ApUserFollow::getUserId,userId));
//        删除被关注的粉丝信息
        apUserFanMapper.delete(Wrappers.<ApUserFan>lambdaQuery()
        .eq(ApUserFan::getFansId,userId)
        .eq(ApUserFan::getUserId,followUserId));
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }


}
